package cc.laop.support;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

/**
 * 扩展 MapperScannerConfigurer, 使basePackage支持通配符
 * 
 * @author Pengpeng
 *
 */
public class WildcardMapperScannerConfigurer extends MapperScannerConfigurer {

	private static final Logger logger = Logger
			.getLogger(WildcardMapperScannerConfigurer.class);

	static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

	@Override
	public void setBasePackage(String basePackage) {
		ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
		MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(
				resolver);
		basePackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
				+ ClassUtils.convertClassNameToResourcePath(basePackage) + "/"
				+ DEFAULT_RESOURCE_PATTERN;

		try {
			Set<String> result = new HashSet<String>();
			Resource[] resources = resolver.getResources(basePackage);
			if (resources != null && resources.length > 0) {
				MetadataReader metadataReader = null;
				for (Resource resource : resources) {
					if (resource.isReadable()) {
						metadataReader = metadataReaderFactory
								.getMetadataReader(resource);
						try {
							result.add(Class
									.forName(metadataReader.getClassMetadata()
											.getClassName())
									.getPackage().getName());
						} catch (ClassNotFoundException e) {
							logger.error(e.getMessage(), e);
						}
					}
				}
			}
			if (result.size() > 0) {
				super.setBasePackage(StringUtils.join(result.toArray(), ","));
			} else {
				logger.warn("参数basePackage:" + basePackage + "，未找到任何包");
			}
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
	}
}
